package spring.my.db.sharding.demo.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import spring.my.db.sharding.demo.annotation.DataSourceAnnotation;
import spring.my.db.sharding.demo.dao.eo.Student;
import spring.my.db.sharding.demo.dao.mapper.StudentMapper;
import spring.my.db.sharding.demo.dto.StudentPageReqDTO;
import spring.my.db.sharding.demo.dto.StudentReqDTO;
import spring.my.db.sharding.demo.dto.StudentResDTO;
import spring.my.db.sharding.demo.exception.BzException;
import spring.my.db.sharding.demo.response.Page;
import spring.my.db.sharding.demo.service.StudentService;

import java.util.*;

@Service
public class StudentServiceImpl implements StudentService {
    private final Logger log = LoggerFactory.getLogger(StudentServiceImpl.class);
    @Autowired
    private StudentMapper studentMapper;

    @Override
    public List<StudentResDTO> list(StudentReqDTO dto) {
        Map<String, Object> params = new HashMap<>();
        params.put("isLimit", true);
        List<Student> list = studentMapper.list(params);
        if (!CollectionUtils.isEmpty(list)) {
            List<StudentResDTO> result = new ArrayList<>();
            StudentResDTO resDTO;
            for (Student student : list) {
                resDTO = new StudentResDTO();
                BeanUtils.copyProperties(student, resDTO);
                result.add(resDTO);
            }
            return result;
        }
        return Collections.emptyList();
    }


    @Override
    public Page<StudentResDTO> page(StudentPageReqDTO dto) {
        Page<StudentResDTO> page = new Page<>(dto);
        Map<String, Object> params = new HashMap<>();
        int count = studentMapper.count(params);
        page.setCount(count);
        if (count <= 0) {
            return page;
        }
        params.put("orders", dto.getOrders());
        params.put("startRow", (dto.getPageNo() - 1) * dto.getPageSize());
        params.put("pageSize", dto.getPageSize());
        List<Student> list = studentMapper.pageQuery(params);
        if (!CollectionUtils.isEmpty(list)) {
            List<StudentResDTO> result = new ArrayList<>();
            StudentResDTO resDTO;
            for (Student student : list) {
                resDTO = new StudentResDTO();
                BeanUtils.copyProperties(student, resDTO);
                result.add(resDTO);
            }
            page.setResult(result);
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(StudentReqDTO dto) throws BzException {
        Student student = new Student();
        BeanUtils.copyProperties(dto, student);
        if (dto.getId() != null && dto.getId() > 0) {
            Student student1 = studentMapper.selectByPrimaryKey(dto.getId());
            if (student1 == null) {
                throw new BzException("can not find update Object by " + dto.getId());
            }
            return studentMapper.updateByPrimaryKeySelective(student) > 0;
        } else {
            int row = studentMapper.insertSelective(student);
            return row > 0;
        }
    }

    @Override
    @DataSourceAnnotation("slave")
    public StudentResDTO detail(Long id) {
        Student student = studentMapper.selectByPrimaryKey(id);
        if (student != null) {
            StudentResDTO result = new StudentResDTO();
            BeanUtils.copyProperties(student, result);
            return result;
        }
        return null;
    }
}
